home *** CD-ROM | disk | FTP | other *** search
/ PC World 2007 January / PCWorld_2007-01_cd.bin / v cisle / hotkey / AutoHotkey104504_Install.exe / AutoHotkey.chm / docs / scripts / minimizetotraymenu.ahk < prev    next >
Text File  |  2006-11-15  |  8KB  |  250 lines

  1. ; Minimize Window to Tray Menu
  2. ; http://www.autohotkey.com
  3. ; This script assigns a hotkey of your choice to hide any window so that
  4. ; it becomes an entry at the bottom of the script's tray menu.  Hidden
  5. ; windows can then be unhidden individually or all at once by selecting
  6. ; the corresponding item on the menu.  If the script exits for any reason,
  7. ; all the windows that it hid will be unhidden automatically.
  8.  
  9. ; CHANGES:
  10. ; July 22, 2005 (changes provided by egilmour):
  11. ; - Added new hotkey to unhide the last hidden window (Win+U)
  12. ;
  13. ; November 3, 2004 (changes provided by trogdor):
  14. ; - Program manager is prevented from being hidden.
  15. ; - If there is no active window, the minimize-to-tray hotkey will have
  16. ;   no effect rather than waiting indefinitely.
  17. ;
  18. ; October 23, 2004:
  19. ; - The taskbar is prevented from being hidden.
  20. ; - Some possible problems with long window titles have been fixed.
  21. ; - Windows without a title can be hidden without causing problems.
  22. ; - If the script is running under AHK v1.0.22 or greater, the
  23. ;   maximum length of each menu item is increased from 100 to 260.
  24.  
  25. ; CONFIGURATION SECTION: Change the below values as desired.
  26.  
  27. ; This is the maximum number of windows to allow to be hidden (having a
  28. ; limit helps performance):
  29. mwt_MaxWindows = 50
  30.  
  31. ; This is the hotkey used to hide the active window:
  32. mwt_Hotkey = #h  ; Win+H
  33.  
  34. ; This is the hotkey used to unhide the last hidden window:
  35. mwt_UnHotkey = #u  ; Win+U
  36.  
  37. ; If you prefer to have the tray menu empty of all the standard items,
  38. ; such as Help and Pause, use N.  Otherwise, use Y:
  39. mwt_StandardMenu = N
  40.  
  41. ; These next few performance settings help to keep the action within the
  42. ; #HotkeyModifierTimeout period, and thus avoid the need to release and
  43. ; press down the hotkey's modifier if you want to hide more than one
  44. ; window in a row.  These settings are not needed you choose to have the
  45. ; script use the keyboard hook via #InstallKeybdHook or other means:
  46. #HotkeyModifierTimeout 100
  47. SetWinDelay 10
  48. SetKeyDelay 0
  49.  
  50. #SingleInstance  ; Allow only one instance of this script to be running.
  51.  
  52. ; END OF CONFIGURATION SECTION (do not make changes below this point
  53. ; unless you want to change the basic functionality of the script).
  54.  
  55. Hotkey, %mwt_Hotkey%, mwt_Minimize
  56. Hotkey, %mwt_UnHotkey%, mwt_UnMinimize
  57.  
  58. ; If the user terminates the script by any means, unhide all the
  59. ; windows first:
  60. OnExit, mwt_RestoreAllThenExit
  61.  
  62. if mwt_StandardMenu = Y
  63.     Menu, Tray, Add
  64. else
  65. {
  66.     Menu, Tray, NoStandard
  67.     Menu, Tray, Add, E&xit and Unhide All, mwt_RestoreAllThenExit
  68. }
  69. Menu, Tray, Add, &Unhide All Hidden Windows, mwt_RestoreAll
  70. Menu, Tray, Add  ; Another separator line to make the above more special.
  71.  
  72. if a_AhkVersion =   ; Since it's blank, version is older than 1.0.22.
  73.     mwt_MaxLength = 100
  74. else
  75.     mwt_MaxLength = 260  ; Reduce this to restrict the width of the menu.
  76.  
  77. return  ; End of auto-execute section.
  78.  
  79.  
  80. mwt_Minimize:
  81. if mwt_WindowCount >= %mwt_MaxWindows%
  82. {
  83.     MsgBox No more than %mwt_MaxWindows% may be hidden simultaneously.
  84.     return
  85. }
  86.  
  87. ; Set the "last found window" to simplify and help performance.
  88. ; Since in certain cases it is possible for there to be no active window,
  89. ; a timeout has been added:
  90. WinWait, A,, 2
  91. if ErrorLevel <> 0  ; It timed out, so do nothing.
  92.     return
  93.  
  94. ; Otherwise, the "last found window" has been set and can now be used:
  95. WinGet, mwt_ActiveID, ID
  96. WinGetTitle, mwt_ActiveTitle
  97. WinGetClass, mwt_ActiveClass
  98. if mwt_ActiveClass in Shell_TrayWnd,Progman
  99. {
  100.     MsgBox The desktop and taskbar cannot be hidden.
  101.     return
  102. }
  103. ; Because hiding the window won't deactivate it, activate the window
  104. ; beneath this one (if any). I tried other ways, but they wound up
  105. ; activating the task bar.  This way sends the active window (which is
  106. ; about to be hidden) to the back of the stack, which seems best:
  107. Send, !{esc}
  108. ; Hide it only now that WinGetTitle/WinGetClass above have been run (since
  109. ; by default, those commands cannot detect hidden windows):
  110. WinHide
  111.  
  112. ; If the title is blank, use the class instead.  This serves two purposes:
  113. ; 1) A more meaningful name is used as the menu name.
  114. ; 2) Allows the menu item to be created (otherwise, blank items wouldn't
  115. ;    be handled correctly by the various routines below).
  116. if mwt_ActiveTitle =
  117.     mwt_ActiveTitle = ahk_class %mwt_ActiveClass%
  118. ; Ensure the title is short enough to fit. mwt_ActiveTitle also serves to
  119. ; uniquely identify this particular menu item.
  120. StringLeft, mwt_ActiveTitle, mwt_ActiveTitle, %mwt_MaxLength%
  121.  
  122. ; In addition to the tray menu requiring that each menu item name be
  123. ; unique, it must also be unique so that we can reliably look it up in
  124. ; the array when the window is later unhidden.  So make it unique if it
  125. ; isn't already:
  126. Loop, %mwt_MaxWindows%
  127. {
  128.     if mwt_WindowTitle%a_index% = %mwt_ActiveTitle%
  129.     {
  130.         ; Match found, so it's not unique.
  131.         ; First remove the 0x from the hex number to conserve menu space:
  132.         StringTrimLeft, mwt_ActiveIDShort, mwt_ActiveID, 2
  133.         StringLen, mwt_ActiveIDShortLength, mwt_ActiveIDShort
  134.         StringLen, mwt_ActiveTitleLength, mwt_ActiveTitle
  135.         mwt_ActiveTitleLength += %mwt_ActiveIDShortLength%
  136.         mwt_ActiveTitleLength += 1 ; +1 the 1 space between title & ID.
  137.         if mwt_ActiveTitleLength > %mwt_MaxLength%
  138.         {
  139.             ; Since menu item names are limted in length, trim the title
  140.             ; down to allow just enough room for the Window's Short ID at
  141.             ; the end of its name:
  142.             TrimCount = %mwt_ActiveTitleLength%
  143.             TrimCount -= %mwt_MaxLength%
  144.             StringTrimRight, mwt_ActiveTitle, mwt_ActiveTitle, %TrimCount%
  145.         }
  146.         ; Build unique title:
  147.         mwt_ActiveTitle = %mwt_ActiveTitle% %mwt_ActiveIDShort%
  148.         break
  149.     }
  150. }
  151.  
  152. ; First, ensure that this ID doesn't already exist in the list, which can
  153. ; happen if a particular window was externally unhidden (or its app unhid
  154. ; it) and now it's about to be re-hidden:
  155. mwt_AlreadyExists = n
  156. Loop, %mwt_MaxWindows%
  157. {
  158.     if mwt_WindowID%a_index% = %mwt_ActiveID%
  159.     {
  160.         mwt_AlreadyExists = y
  161.         break
  162.     }
  163. }
  164.  
  165. ; Add the item to the array and to the menu:
  166. if mwt_AlreadyExists = n
  167. {
  168.     Menu, Tray, add, %mwt_ActiveTitle%, RestoreFromTrayMenu
  169.     mwt_WindowCount += 1
  170.     Loop, %mwt_MaxWindows%  ; Search for a free slot.
  171.     {
  172.         ; It should always find a free slot if things are designed right.
  173.         if mwt_WindowID%a_index% =  ; An empty slot was found.
  174.         {
  175.             mwt_WindowID%a_index% = %mwt_ActiveID%
  176.             mwt_WindowTitle%a_index% = %mwt_ActiveTitle%
  177.             break
  178.         }
  179.     }
  180. }
  181. return
  182.  
  183.  
  184. RestoreFromTrayMenu:
  185. Menu, Tray, delete, %A_ThisMenuItem%
  186. ; Find window based on its unique title stored as the menu item name:
  187. Loop, %mwt_MaxWindows%
  188. {
  189.     if mwt_WindowTitle%a_index% = %A_ThisMenuItem%  ; Match found.
  190.     {
  191.         StringTrimRight, IDToRestore, mwt_WindowID%a_index%, 0
  192.         WinShow, ahk_id %IDToRestore%
  193.         WinActivate ahk_id %IDToRestore%  ; Sometimes needed.
  194.         mwt_WindowID%a_index% =  ; Make it blank to free up a slot.
  195.         mwt_WindowTitle%a_index% =
  196.         mwt_WindowCount -= 1
  197.         break
  198.     }
  199. }
  200. return
  201.  
  202.  
  203. ;; This will pop the last minimized window off the stack and unhide it.
  204. mwt_UnMinimize:
  205. ;; Make sure there's something to unhide.
  206. if mwt_WindowCount > 0 
  207. {
  208.     ;; Get the id of the last window minimized and unhide it
  209.     StringTrimRight, IDToRestore, mwt_WindowID%mwt_WindowCount%, 0
  210.     WinShow, ahk_id %IDToRestore%
  211.     WinActivate ahk_id %IDToRestore%
  212.     
  213.     ;; Get the menu name of the last window minimized and remove it
  214.     StringTrimRight, MenuToRemove, mwt_WindowTitle%mwt_WindowCount%, 0
  215.     Menu, Tray, delete, %MenuToRemove%
  216.     
  217.     ;; clean up our 'arrays' and decrement the window count
  218.     mwt_WindowID%mwt_WindowCount% =
  219.     mwt_WindowTitle%mwt_WindowCount% = 
  220.     mwt_WindowCount -= 1
  221. }
  222. return
  223.  
  224.  
  225. mwt_RestoreAllThenExit:
  226. Gosub, mwt_RestoreAll
  227. ExitApp  ; Do a true exit.
  228.  
  229.  
  230. mwt_RestoreAll:
  231. Loop, %mwt_MaxWindows%
  232. {
  233.     if mwt_WindowID%a_index% <>
  234.     {
  235.         StringTrimRight, IDToRestore, mwt_WindowID%a_index%, 0
  236.         WinShow, ahk_id %IDToRestore%
  237.         WinActivate ahk_id %IDToRestore%  ; Sometimes needed.
  238.         ; Do it this way vs. DeleteAll so that the sep. line and first
  239.         ; item are retained:
  240.         StringTrimRight, MenuToRemove, mwt_WindowTitle%a_index%, 0
  241.         Menu, Tray, delete, %MenuToRemove%
  242.         mwt_WindowID%a_index% =  ; Make it blank to free up a slot.
  243.         mwt_WindowTitle%a_index% =
  244.         mwt_WindowCount -= 1
  245.     }
  246.     if mwt_WindowCount = 0
  247.         break
  248. }
  249. return
  250.